package proyecto1IA;

import static java.awt.Component.CENTER_ALIGNMENT;
import java.awt.*;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class PanelJuego extends JPanel {

    public JPanel cuadroJuego;
    public JLabel matriz[][];
    public static int matrizPosiciones[][], matrizPesos[][];
    public static Point robot, objeto1, objeto2, lugar1, lugar2;
    public Border borde = BorderFactory.createLineBorder(Color.BLACK, 1);
    public static int filaColumna, pesoObj1, pesoObj2;
    ArrayList<Point> listaSolucion;
    public Thread hilo;

    public PanelJuego(Scanner entrada) {

        hilo = new Thread() {
            @Override
            public void run() {
                iniciar();
            }
        };

        //Revisamos la Primera linea del Archivo que contiene el tamaño de de la cuadricula, y los pesos de los objetos.
        chequeoInicial(entrada.nextLine());

        //Instanciamos la matriz de posiciones y usamos la funcion escribirMatrizPosiciones para escribir los valores sobre la matrizPosiciones.
        matrizPosiciones = new int[filaColumna][filaColumna];
        matrizPesos = new int[filaColumna][filaColumna];

        try {
            for (int fila = 0; fila < filaColumna; fila++) {
                String[] filaSplit = entrada.nextLine().split(" ");
                if (filaSplit.length > filaColumna) {
                    throw new Exception();
                } else {
                    for (int columna = 0; columna < filaColumna; columna++) {
                        matrizPosiciones[columna][fila] = Integer.parseInt(filaSplit[columna]);
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException exp) {
            p("Exception oob");
            System.out.println("Matriz mal escrita en el archivo. Recuerde que debe tener " + filaColumna + " filas y columnas.");
        } catch (Exception expIf) {
            p("Exception if");
            System.out.println("Matriz mal escrita en el archivo. Recuerde que debe tener " + filaColumna + " filas y columnas.");
        }
        //Pintamos el cuadro de Juego.
        setLayout(new GridBagLayout());

        this.setOpaque(false);
        cuadroJuego = new JPanel(new GridLayout(filaColumna, filaColumna));
        cuadroJuego.setOpaque(false);

        pintarMatriz();
        add(cuadroJuego);

    }

    private void chequeoInicial(String primeraFila) {

        String[] datosPrimeraFila = primeraFila.split(" ");

        filaColumna = Integer.parseInt(datosPrimeraFila[0]);
        pesoObj1 = Integer.parseInt(datosPrimeraFila[1]);
        pesoObj2 = Integer.parseInt(datosPrimeraFila[2]);
    }

    private void pintarMatriz() {

        ImageIcon imagenFondo = new ImageIcon(getClass().getResource("robot.png"));
        inicializarMatrizLabels(filaColumna);

        for (int columna = 0; columna < filaColumna; columna++) {

            for (int fila = 0; fila < filaColumna; fila++) {

                if (matrizPosiciones[fila][columna] == 0) {

                    matriz[fila][columna].setBackground(Color.WHITE);
                    matrizPesos[columna][fila] = 1;

                }else if (matrizPosiciones[fila][columna] == -1) {

                    matriz[fila][columna].setIcon(imagenFondo);
                    matriz[fila][columna].setBackground(Color.RED);
                    matrizPesos[columna][fila] = 1;
                    robot = new Point(columna, fila);

                } else if (matrizPosiciones[fila][columna] == -2) {

                    matriz[fila][columna].setBackground(Color.GREEN);
                    matriz[fila][columna].setText("OBJ1");
                    matrizPesos[columna][fila] = pesoObj1;
                    objeto1 = new Point(columna, fila);

                } else if (matrizPosiciones[fila][columna] == -3) {

                    matriz[fila][columna].setBackground(Color.GREEN);
                    matriz[fila][columna].setText("OBJ2");
                    matrizPesos[columna][fila] = pesoObj2;
                    objeto2 = new Point(columna, fila);

                } else if (matrizPosiciones[fila][columna] == -4) {

                    matriz[fila][columna].setBackground(Color.GRAY);
                    matriz[fila][columna].setText("BAS1");
                    matrizPesos[columna][fila] = 1;
                    lugar1 = new Point(columna, fila);

                } else if (matrizPosiciones[fila][columna] == -5) {

                    matriz[fila][columna].setBackground(Color.GRAY);
                    matriz[fila][columna].setText("BAS2");
                    matrizPesos[columna][fila] = 1;
                    lugar2 = new Point(columna, fila);

                } else {
                    matriz[fila][columna].setBackground(Color.WHITE);
                    matrizPesos[columna][fila] = matrizPosiciones[fila][columna];
                    if (matrizPosiciones[fila][columna] != 0) {
                        matriz[fila][columna].setText(matrizPosiciones[fila][columna] + "");
                    }
                }
                cuadroJuego.add(matriz[fila][columna]);

            }//fin for interno

        } //fin for externo
        
    }//fin metodo pintar matriz

    private void inicializarMatrizLabels(int tamanioMatriz) {

        matriz = new JLabel[tamanioMatriz][tamanioMatriz];

        for (int fila = 0; fila < tamanioMatriz; fila++) {

            for (int columna = 0; columna < tamanioMatriz; columna++) {

                matriz[fila][columna] = new JLabel();
                matriz[fila][columna].setBorder(borde);
                matriz[fila][columna].setPreferredSize(new Dimension(40, 40));
                matriz[fila][columna].setVerticalAlignment((int) CENTER_ALIGNMENT);
                matriz[fila][columna].setHorizontalAlignment((int) CENTER_ALIGNMENT);
                matriz[fila][columna].setOpaque(true);
            }
        }

    }//fin metodo inicializarMatrizLabels

    public void inicializarSolucion(ArrayList<ArrayList<Point>> solucion) {

        listaSolucion = new ArrayList<Point>();

        for (int i = 0; i < solucion.get(0).size(); i++) {

            listaSolucion.add(recorrerArrayList(solucion, 0, i));
        }
        for (int i = 0; i < solucion.get(1).size(); i++) {

            listaSolucion.add(recorrerArrayList(solucion, 1, i));
        }
        for (int i = 0; i < solucion.get(2).size(); i++) {

            listaSolucion.add(recorrerArrayList(solucion, 2, i));
        }
        for (int i = 0; i < solucion.get(3).size(); i++) {

            listaSolucion.add(recorrerArrayList(solucion, 3, i));
        }

        //eliminando elementos repetidos
        for (int i = 0; i < listaSolucion.size() - 1; i++) {

            if (listaSolucion.get(i).equals(listaSolucion.get(i + 1))) {
                //tenemos elementos repetidos, entonces eliminados uno de ellos
                listaSolucion.remove(i);
            }
        }
//        //imprimiendo
//        for (int i = 0; i < listaSolucion.size(); i++) {
//
//            p("" + listaSolucion.get(i));
//        }
    }

    public Point recorrerArrayList(ArrayList<ArrayList<Point>> solucion, int arreglo, int posicion) {

        return solucion.get(arreglo).get(posicion);
    }

    public void iniciar() {

        int i = 0;
        Point anterior = robot;
        ImageIcon imagenRobot = new ImageIcon(getClass().getResource("robot.png"));
        //ImageIcon imagenEnBlanco = new ImageIcon(getClass().getResource("blanco.jpg"));

        while (i < listaSolucion.size()) {

            matriz[listaSolucion.get(i).y][listaSolucion.get(i).x].setIcon(imagenRobot);
            matriz[anterior.y][anterior.x].setIcon(null);
            anterior = listaSolucion.get(i);
            i++;
            try {
                Thread.sleep(600);
            } catch (InterruptedException ex) {
                p("Ha ocurrido un error con el hilo");
            }
        }

    }//fin metodo iniciar
    public void ps(Object mensaje) {
        System.out.print(mensaje + " ");
    }
    
    public void p(Object mensaje) {
        System.out.println(mensaje);
    }
}